package edu.isquen.core.base.dao;

import java.util.Collection;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import edu.isquen.core.base.model.ValueObject;

/****************************************************
* 文件名：BaseDAO.java
* 文件描述：DAO基层实体类
* 创建人： isquen, 2011 年6 月10 日
* 版本号：1.0
* 修改记录：
****************************************************/
public class BaseDAO<E> implements IBaseDAO<E> {

	private static Log log = LogFactory.getLog(BaseDAO.class);

	private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
	private static Configuration configuration = new Configuration();
	private static SessionFactory sessionFactory = null;
	public String voClazzName;

	public BaseDAO(String voClazzName) {
		this.voClazzName = voClazzName;
	}

	public BaseDAO() {
	}

	public static SessionFactory getSessionFactory() {
		if (sessionFactory == null) {
			configuration.configure();
			sessionFactory = configuration.buildSessionFactory();
		}
		return sessionFactory;
	}

	public static void closeSession() throws HibernateException {
		Session session = (Session) threadLocal.get();
		threadLocal.set(null);

		if (session != null) {
			session.close();
		}
	}

	public Session getSession() {
		Session session = (Session) threadLocal.get();
		if (session == null || !session.isOpen()) {
			if (sessionFactory == null) {
				getSessionFactory();
			}
			session = (sessionFactory != null) ? sessionFactory.openSession()
					: null;
			threadLocal.set(session);
		}
		return session;
	}

	public void create(Object obj) throws Exception {
		Session session = (Session) this.getSession();
		Transaction tx = session.beginTransaction();
		try {
			session.save(obj);
			tx.commit();
			session.flush();
		} catch (Exception e) {
			log.debug("======Catch Exception--->" + e);
		} finally {
			session.close();
		}
	}

	@SuppressWarnings("unchecked")
	public ValueObject find(String key) throws Exception {
		Session session = getSession();
		ValueObject rtn = null;
		String sql = "from " + this.voClazzName + " where id='" + key + "'";
		try {
			Query query = session.createQuery(sql);
			query.setFirstResult(0);
			query.setMaxResults(1);
			List<ValueObject> result = query.list();
			if (!result.isEmpty()) {
				rtn = (ValueObject) result.get(0);
			}
		} catch (Exception e) {
			log.debug("======Catch Exception --->" + e);
		} finally {
			session.close();
		}
		return rtn;
	}

	public DataPackage<E> findByAny(ValueObject obj) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public ValueObject getData(String sql) throws Exception {
		Session session = getSession();
		ValueObject rtn = null;
		try {
			Query query = session.createQuery(sql);
			rtn = (ValueObject) query.list();
		} catch (Exception e) {
			log.debug("======Catch Exception --->" + e);
		} finally {
			session.close();
		}
		return rtn;
	}

	@SuppressWarnings("unchecked")
	public DataPackage<E> getDatas(String hql) throws Exception {
		Session session = getSession();
		DataPackage<E> result = new DataPackage<E>();
		try {
			Query query = session.createQuery(hql);
			Collection<E> datas = query.list();
			result.setDatas(datas);
		} catch (Exception e) {
			log.debug("======Catch Exception --->" + e);
		} finally {
			session.close();
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	public DataPackage<E> getDatasBySql(String sql) throws Exception {
		Session session = this.getSession();
		DataPackage<E> result = new DataPackage<E>();
		try {
			SQLQuery query = session.createSQLQuery(sql);
			query.addEntity(Class.forName(this.voClazzName));
			// query.setFirstResult((page - 1) * lines);
			// query.setMaxResults(lines);
			Collection<E> datas = query.list();
			result.setDatas(datas);
		} catch (Exception e) {
			log.debug("======Catch Exception --->" + e);
		} finally {
			session.close();
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	public DataPackage<E> getDatas() throws Exception {
		Session session = getSession();
		String sql = "from " + this.voClazzName;
		DataPackage<E> result = new DataPackage<E>();
		try {
			Query query = session.createQuery(sql);
			Collection<E> datas = query.list();
			result.setDatas(datas);
			session.flush();
		} catch (Exception e) {
			log.debug("======Catch Exception --->" + e);
		} finally {
			session.close();
		}
		return result;
	}

	public DataPackage<E> getDatas(String dql, String params) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@SuppressWarnings("unchecked")
	public DataPackage<E> getDatas(String sql, int page, int line) {
		Session session = getSession();
		DataPackage<E> result = new DataPackage<E>();
		try {
			Query query = session.createQuery(sql);
			query.setFirstResult(page);
			query.setMaxResults(line);
			Collection<E> datas = query.list();
			result.setDatas(datas);
			session.flush();
		} catch (Exception e) {
			log.debug("======Catch Exception --->" + e);
		} finally {
			session.close();
		}
		return result;
	}

	public int getTotalLines(String dql) throws Exception {
		// TODO Auto-generated method stub
		return 0;
	}

	public void remove(String key) throws Exception {
		ValueObject vo = find(key);
		Session session = getSession();
		Transaction tx = session.beginTransaction();
		try {
			if (vo != null) {
				session.delete(vo);
				tx.commit();
			}
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
		}finally{
			session.close();
		}
	}

	public void remove(String[] keys) throws Exception {
		// TODO Auto-generated method stub

	}

	public void remove(ValueObject obj) throws Exception {
		Session session = getSession();
		Transaction tx = session.beginTransaction();
		try {
			session.delete(obj);
			tx.commit();
		} catch (Exception e) {
			log.debug("======Catch Exception --->" + e);
			tx.rollback();
		} finally {
			session.close();
		}
	}

	public void update(Object obj) throws Exception {
		// TODO Auto-generated method stub
		Session session = (Session) this.getSession();
		Transaction tx = session.beginTransaction();
		try {
			session.merge(obj);
			tx.commit();
		} catch (Exception e) {
			log.debug("======Catch Exception--->" + e);
			tx.rollback();
		} finally {
			session.close();
		}
	}
}
